<!-- ukey主要功能：1、客户端生成私钥，2、服务端对公钥签名，3、写到ukey，4、读取ukey公钥证书，5、签名 -->
<template>
  <div style="padding-top: 50px">
    <input id="seal-upload" type="file" style="display: none" @change="uploadSealHandle" />
    <input id="pdf-upload" type="file" style="display: none" @change="uploadPDFHandle" />
    <input id="seal-matting" type="file" style="display: none" @change="sealMattingHandle" />
    <el-dialog
      title="制作证书"
      width="500px"
      :visible.sync="dialogFormVisible"
      :close-on-click-modal="false"
    >
      <el-form :model="form" label-position="top">
        <el-form-item label="UKey名称">
          <el-input v-model="form.userName" autocomplete="off"></el-input>
        </el-form-item>
        <el-form-item label="UKey序列号">
          <el-input v-model="form.userId" autocomplete="off"></el-input>
        </el-form-item>
        <el-form-item label="类型">
          <el-select v-model="form.type" placeholder="请选择类型" style="width: 100%">
            <el-option label="单位" value="unit"></el-option>
            <el-option label="用户" value="user"></el-option>
          </el-select>
        </el-form-item>
      </el-form>
      <div slot="footer" class="dialog-footer">
        <el-button @click="dialogFormVisible = false">取 消</el-button>
        <el-button type="primary" @click="doMakeCert">确 定</el-button>
      </div>
    </el-dialog>

    <el-dialog
      title="自动签章"
      width="500px"
      :visible.sync="autoSealDialog"
      :close-on-click-modal="false"
    >
      <el-form :model="sealform" label-position="top">
        <!-- <el-form-item label="文档id">
          <el-input v-model="sealform.id" autocomplete="off"></el-input>
        </el-form-item>-->
        <el-form-item label="签章位置">
          <el-input v-model="sealform.seals" autocomplete="off"></el-input>
        </el-form-item>
        <el-form-item label="骑缝章位置">
          <el-input v-model="sealform.paging" autocomplete="off"></el-input>
        </el-form-item>
      </el-form>
      <div slot="footer" class="dialog-footer">
        <el-button @click="autoSealDialog = false">取 消</el-button>
        <el-button type="danger" size="small" @click="beforePDFUpload">上传需要签名的PDF</el-button>
      </div>
    </el-dialog>
    <el-dialog
      title="ukey信息"
      width="600px"
      :visible.sync="showUkeyDialog"
      :close-on-click-modal="false"
    >
      <el-form label-position="top">
        <el-form-item label="ukey信息">{{ msg }}</el-form-item>
        <el-form-item label="印章信息">
          <el-image class="seal" :src="sealimg">
            <div slot="error" class="image-slot">无印章</div>
          </el-image>
        </el-form-item>
      </el-form>
      <div slot="footer" class="dialog-footer">
        <el-button @click="showUkeyDialog = false">取 消</el-button>
      </div>
    </el-dialog>
    <div class="user-table">
      <h3>UKEY管理</h3>
      <div class="header-text">{{ cainfo }}</div>
      <div style="margin-bottom: 10px">
        <el-button @click="dialogFormVisible = true">制作证书</el-button>
        <el-button @click="readUkey">读ukey</el-button>
        <!-- <el-button @click="signData">签名</el-button> -->
        <el-button @click="matting">印章扣图</el-button>
        <el-button @click="autoSealDialog = true">测试自动签章</el-button>
        <el-button @click="gotoSeal">在线签章</el-button>
        <el-input placeholder="请输入内容" v-model="seatchText" clearable class="search">
          <el-button slot="append" icon="el-icon-search" @click="seatchHandle"></el-button>
        </el-input>
      </div>
      <el-table :data="tableData" border class="table" height="calc(100vh - 300px)">
        <el-table-column prop="userName" label="UKey名称"></el-table-column>
        <el-table-column prop="userId" label="UKey序列号"></el-table-column>
        <el-table-column prop="type" label="类型" align="center">
          <template slot-scope="scope">
            <span>{{ scope.row.type === 'unit' ? '单位' : '用户' }}</span>
          </template>
        </el-table-column>
        <!-- <el-table-column prop="sealStatus" label="绑定印章" align="center">
          <template slot-scope="scope">
            <el-popover
              placement="right"
              v-if="scope.row.sealStatus === '是'"
              @show="showSealImg(scope.row.userId)"
              trigger="click"
            >
              <el-image style="width: 200px; height: 200px" :src="sealimg"></el-image>
              <el-link slot="reference">是</el-link>
            </el-popover>
            <span v-else>否</span>
          </template>
        </el-table-column> -->
        <el-table-column prop="createTime" label="创建时间"></el-table-column>
        <el-table-column prop="lastUpdateTime" label="更新时间"></el-table-column>
        <el-table-column label="有效日期">
          <template slot-scope="scope">
            <span>{{scope.row.lastUpdateTime | dateHandle}}</span>
          </template>
        </el-table-column>

        <el-table-column label="操作" align="center">
          <template slot-scope="scope">
            <!-- <el-button @click="beforeSealUpload(scope.row)" type="text" size="small">绑定印章</el-button> -->
            <el-button @click="deleteCert(scope.row)" type="text" size="small">删除</el-button>
          </template>
        </el-table-column>
      </el-table>
      <el-pagination
        background
        layout="total, prev, pager, next"
        @current-change="handleCurrentChange"
        :current-page="page.current"
        :page-size="page.size"
        :total="page.total"
      ></el-pagination>
    </div>
  </div>
</template>

<script>
import axios from 'axios'
import { makeCert, decodeCert, signData, ukeySeal } from './common/ukey'
import moment from 'moment'
import SealMatting from './common/seal-matting'
export default {
  data() {
    return {
      form: {
        userName: '林丹',
        userId: '18701503529',
        type: 'user'
      },
      sealform: {
        id: '',
        seals: `[{ page: 1, x: 100, y: 100 }]`,
        paging: `{ y: 200 }`
      },
      page: {
        current: 1,
        size: 10,
        total: 0,
        searchText: ''
      },
      seatchText: '',
      msg: '',
      sealimg: '',
      certInfo: '',
      src: '',
      signResult: '',
      serialNumber: '', // 证书序号
      dialogFormVisible: false,
      autoSealDialog: false,
      showUkeyDialog: false,
      currentCert: {},
      cainfo: '',
      baseurl: process.env.VUE_APP_SEAL_BASE_PATH,
      userContainer: '9160a3d4-137c-4523-9f02-b9f140a153d7', // 用户证书容器
      caContainer: '06D5EEFD-52B3-4F65-99AB-AE683FEDD624', // ca证书容器
      rootContainer: '06D5EEFD-52B3-4F65-99AB-AE683FEDD623', // root证书容器
      tableData: []
    }
  },
  mounted() {
    this.loadData()
    this.loadCaInfo()
  },
  filters: {
    dateHandle(value) {
      return moment(value).add(30, 'Y').format('YYYY-MM-DD')
    }
  },
  methods: {
    matting() {
      document.getElementById('seal-matting').click()
    },
    gotoSeal() {
      // 确定
      const { href } = this.$router.resolve({
        path: '/seal',
        query: {
          type: 'ukey'
        }
      })
      window.open(href, '_blank')
    },
    seatchHandle() {
      this.page.current = 1
      this.page.searchText = this.seatchText
      this.loadData()
    },
    handleCurrentChange(val) {
      this.page.current = val
      this.loadData()
    },
    loadCaInfo() {
      this.$http.post(`${this.baseurl}/cert/ca`, {}).then((res) => {
        console.log('loadCaInfo', res)
        this.cainfo = res.data
      })
    },
    async deleteCert(item) {
      let flag = await this.$confirm('确定删除证书数据吗?', '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      })
        .then(() => {
          return true
        })
        .catch(() => {
          return false
        })
      if (!flag) {
        return
      }
      this.$http
        .post(`${this.baseurl}/cert/deletCert`, {
          id: item.id
        })
        .then((res) => {
          console.log(res)
          if (res.status === 0) {
            this.$message({
              message: '已删除',
              type: 'success'
            })
            this.loadData()
          }
        })
    },
    loadData() {
      this.$http
        .post(`${this.baseurl}/cert/selectPage`, this.page)
        .then((res) => {
          console.log('loadData', res)
          this.tableData = res.data.records
          this.page.total = res.data.total
        })
    },
    beforeSealUpload(row) {
      // 上传前
      this.currentCert = row
      document.getElementById('seal-upload').click()
    },
    beforePDFUpload() {
      // 上传前
      document.getElementById('pdf-upload').click()
    },
    sealMattingHandle(obj) {
      if (!obj.target.files) {
        return
      }
      let file = obj.target.files[0]
      let mat = new SealMatting(file)
      mat.createStream()
      document.getElementById('seal-matting').value = ''
    },
    uploadPDFHandle(obj) {
      // 上传
      // 2.如果没有选中文件则取消
      if (!obj.target.files) {
        return
      }
      this.loadingMsg = 'PDF处理中'
      this.loading = true
      // 3.获得选择的文件对象
      let file = obj.target.files[0]
      let formData = new FormData()
      formData.append('file', file)
      // 异步处理
      formData.append('async', true)
      axios
        .post(`${this.baseurl}/pdf/upload`, formData, {
          headers: { 'Content-Type': 'multipart/form-data' }
        })
        .then((res) => {
          console.log(res)
          this.loading = false
          this.showPDF = false
          if (res.status === 200 && res.data.status === 0) {
            let { id } = res.data.data
            this.sealform.id = id
            // 开始签章
            this.ukeySealHanlde()
            document.getElementById('pdf-upload').value = ''
            this.$message({
              message: '上传成功',
              type: 'success'
            })
          }
        })
        .catch((err) => {
          console.error(err)
          this.loading = false
          document.getElementById('pdf-upload').value = ''
          this.$message({
            message: '上传失败',
            type: 'error'
          })
        })
    },
    async uploadSealHandle(obj) {
      if (!obj.target.files) {
        return
      }
      // let { serialNumber } = await decodeCert(`${this.baseurl}/cert/info`)
      // this.serialNumber = serialNumber
      // if (!serialNumber) {
      //   this.$message({
      //     message: '读取ukey失败',
      //     type: 'error'
      //   })
      //   return
      // }
      let file = obj.target.files[0]
      let formData = new FormData()
      formData.append('file', file)
      formData.append('serialNumber', this.currentCert.userId)
      axios
        .post(`${this.baseurl}/pdf/seal/upload`, formData, {
          headers: { 'Content-Type': 'multipart/form-data' }
        })
        .then((res) => {
          console.log(res)
          if (res.status === 200 && res.data.status === 0) {
            this.$message({
              message: '绑定成功',
              type: 'success'
            })
          }
          this.loadData()
          document.getElementById('seal-upload').value = ''
        })
        .catch((err) => {
          console.error(err)
          document.getElementById('seal-upload').value = ''
          this.$message({
            message: '绑定失败',
            type: 'error'
          })
        })
    },
    compress(base64String, w, quality) {
      let getMimeType = function (urlData) {
        let arr = urlData.split(',')
        let mime = arr[0].match(/:(.*?);/)[1]
        // return mime.replace("image/", "");
        return mime
      }
      let newImage = new Image()
      let imgWidth, imgHeight

      let promise = new Promise((resolve) => (newImage.onload = resolve))
      newImage.src = base64String
      return promise.then(() => {
        imgWidth = newImage.width
        imgHeight = newImage.height
        let canvas = document.createElement('canvas')
        let ctx = canvas.getContext('2d')
        if (Math.max(imgWidth, imgHeight) > w) {
          if (imgWidth > imgHeight) {
            canvas.width = w
            canvas.height = (w * imgHeight) / imgWidth
          } else {
            canvas.height = w
            canvas.width = (w * imgWidth) / imgHeight
          }
        } else {
          canvas.width = imgWidth
          canvas.height = imgHeight
        }
        ctx.clearRect(0, 0, canvas.width, canvas.height)
        ctx.drawImage(newImage, 0, 0, canvas.width, canvas.height)
        let base64 = canvas.toDataURL(getMimeType(base64String), quality)
        console.log(base64)
        return base64
      })
    },
    async exists() {
      return this.$http
        .post(`${this.baseurl}/cert/exists`, { userId: this.form.userId })
        .then(async (res) => {
          console.log(res)
          if (res.data) {
            return true
          }
          let flag = await this.$confirm(
            '已经存在相同的序列号, 是否继续?',
            '提示',
            {
              confirmButtonText: '确定',
              cancelButtonText: '取消',
              type: 'warning'
            }
          )
            .then(() => {
              return true
            })
            .catch(() => {
              return false
            })
          return flag
        })
    },
    async doMakeCert() {
      let flag = await this.exists()
      if (!flag) {
        return
      }
      makeCert(
        `${this.baseurl}/cert/makeUserCert`,
        this.form.userId,
        this.form.userName,
        this.form.type,
        true
      ).then((res) => {
        console.log(res)
        if (res.status) {
          this.$notify({
            title: '提示',
            message: '制作证书成功',
            type: 'success'
          })
          this.dialogFormVisible = false
          this.loadData()
        } else {
          this.$notify({
            title: '警告',
            message: res.msg,
            type: 'warning'
          })
        }
      })
    },
    loadRemoteData(url, params) {
      return this.$http
        .post(url, params)
        .then((res) => {
          console.log(res)
          if (res.status === 0) {
            return res.data
          } else {
            return false
          }
        })
        .catch((err) => {
          console.log(err)
          return false
        })
    },
    async showSealImg(serialNumber) {
      let result = await this.loadRemoteData(`${this.baseurl}/pdf/seal/img`, {
        serialNumber
      })
      if (result) {
        this.sealimg = 'data:image/png;base64,' + result
      } else {
        this.sealimg = ''
      }
    },
    readUkey() {
      return decodeCert(`${this.baseurl}/cert/info`).then(async (cert) => {
        console.log(cert)
        if (!cert) {
          this.$message({
            message: '读取ukey失败',
            type: 'error'
          })
          return false
        }
        this.serialNumber = cert.serialNumber
        this.msg = cert
        if (!this.serialNumber) {
          this.$message({
            message: '读取ukey失败',
            type: 'error'
          })
          return
        }
        this.showSealImg(this.serialNumber)
        this.showUkeyDialog = true
        return true
      })
    },
    signData() {
      // 签名
      this.signResult = signData(this.src, false)
      console.log('this.signResult', this.signResult)
    },
    ukeySealHanlde() {
      ukeySeal({
        id: this.sealform.id,
        seals: this.sealform.seals && eval(`(${this.sealform.seals})`),
        paging: this.sealform.paging && eval(`(${this.sealform.paging})`)
      })
        .then((res) => {
          this.autoSealDialog = false
          console.log('签章结果', res)
          this.$confirm('电子签章完成，是否预览刚签署的pdf文件?', '提示', {
            confirmButtonText: '确定',
            cancelButtonText: '取消',
            type: 'warning'
          }).then(() => {
            // 确定
            const { href } = this.$router.resolve({
              path: '/seal',
              query: {
                id: this.sealform.id,
                type: 'ukey'
              }
            })
            window.open(href, '_blank')
          })
        })
        .catch((err) => {
          console.log('签章结果 错误', err)
        })
    }
  }
}
</script>

<style lang="scss" scoped>
.user-table {
  width: 80%;
  background-color: #fff;
  padding: 20px 10px;
  margin: 0 auto;
}
.search {
  width: 250px;
  float: right;
}
.header-text {
  margin-bottom: 15px;
  color: #787878;
}
.seal {
  width: 150px;
  height: 150px;
  border: 1px solid #ccc;
  justify-content: center;
  align-items: center;
  display: flex;
}
.table {
  width: 100%;
}
</style>
